#ifndef GAMELOGIC_LEVEL_LEVEL_H_
#define GAMELOGIC_LEVEL_LEVEL_H_

#include <map>

#include "../Objects/GameObject.h"
#include "./TileMap.h"

namespace GameLogic {
namespace Level {

class Level {
public:
	typedef std::map< Objects::GameObject::IdType, Objects::GameObject* > MapType;
	typedef std::pair< Objects::GameObject::IdType, Objects::GameObject* > MapPair;
	typedef MapType::iterator MapIter;
private:
	MapType objects_;
	TileMap tiles_;
	Vec2f spawn_points_[ 2 ];
public:

	Level( int width, int height, float tile_size );

	~Level();

	MapIter objectsBegin() {
		return objects_.begin();
	}

	MapIter objectsEnd() {
		return objects_.end();
	}

	/*
	 * Zwraca obiekt o podanym id, lub NULL jesli obiekt nie istnieje.
	 *
	 * UWAGA! NULL takze nie istnieje, ale przyjmijmy, ze NULL to 0.
	 */
	Objects::GameObject* getObject( Objects::GameObject::IdType id ) {
		MapIter obj = objects_.find( id );
		if( obj != objects_.end() ) return (*obj).second;
		else return 0;
	}

	void insertObject( Objects::GameObject* go ) {
		objects_.insert( MapPair( go->getId(), go ) );
	}

	/*
	 * Pobiera wybrany tile.
	 */
	Tile* getTile( int x, int y );

	/*//PEWNO OBSOLETE :P
	 * Ustawia Tile na wybranej pozycji i przejmuje wlasnosc nad nim.
	 */
	void setTile( int x, int y, Tile* tile ) {
		tiles_.set( x, y, tile );
	}

	/*
	 * Wstawia Tile na wybranej pozycji i przejmuje wlasnosc nad nim. (wola metode onInsert)
	 */
	void insertTile( int x, int y, Tile* tile ) {
		tiles_.insert( x, y, tile );
	}

	float getTileSize() { return tiles_.getTileSize(); }

	int getWidth() { return tiles_.getWidth(); }

	int getHeight() { return tiles_.getHeight(); }

	/*
	 * Zwraca spawn point zadanego teamu.
	 */
	Vec2f getSpawnPoint( unsigned char team_id ) {
		return spawn_points_[ team_id ];
	}

	/*
	 * Ustawia spawn point zadanego teamu.
	 */
	void setSpawnPoint( unsigned char team_id, const Vec2f& point ) {
		spawn_points_[ team_id ] = point;
	}

	/*
	 * Przygotowuje Level do uruchomienia, wolane przez serwer tuz przed uruchomieniem
	 * glownej petli gry.
	 */
	void deployOnServer();

};

typedef Level::MapType ObjectMapType;
typedef Level::MapPair ObjectMapPair;
typedef Level::MapIter ObjectMapIter;

} //namespace Level
} //namespace GameLogic

#endif /* GAMELOGIC_LEVEL_LEVEL_H_ */
